package com.yuhong.springbootinit.controller;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.yuhong.springbootinit.annotation.AuthCheck;
import com.yuhong.springbootinit.model.dto.applicant.UpdateApplicantAndProfileRequest;
import com.yuhong.springbootinit.model.entity.Profile;
import com.yuhong.springbootinit.model.entity.UserProfile;
import com.yuhong.springbootinit.service.ApplicantService;
import com.yuhong.springbootinit.service.ProfileService;
import com.yuhong.springbootinit.service.UserProfileService;
import com.yuhong.springbootinit.service.UserService;
import com.yuhong.springbootinit.common.BaseResponse;
import com.yuhong.springbootinit.common.ErrorCode;
import com.yuhong.springbootinit.common.ResultUtils;
import com.yuhong.springbootinit.constant.UserConstant;
import com.yuhong.springbootinit.exception.BusinessException;
import com.yuhong.springbootinit.exception.ThrowUtils;
import com.yuhong.springbootinit.model.dto.applicant.ApplicantQueryRequest;
import com.yuhong.springbootinit.model.dto.applicant.ApplicantUpdateMyRequest;
import com.yuhong.springbootinit.model.entity.Applicant;
import com.yuhong.springbootinit.model.entity.User;
import com.yuhong.springbootinit.model.vo.ApplicantVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/applicant")
@Slf4j
public class ApplicantController {

    @Resource
    private ApplicantService applicantService;


    @Resource
    private UserService userService;

    @Resource
    private UserProfileService userProfileService;

    @Resource
    private ProfileService profileService;


    /**
     * 根据 id 获取
     *
     * @param id
     * @return
     */
    @GetMapping("/get/vo")
    public BaseResponse<ApplicantVO> getApplicantVOById(long id, HttpServletRequest request) throws JsonProcessingException {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        Applicant applicant = applicantService.getById(id);
        if (applicant == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        return ResultUtils.success(applicantService.getApplicantVO(applicant, request));
    }

    /**
     * 分页获取列表（仅管理员）
     *
     * @param postQueryRequest
     * @return
     */
    @PostMapping("/list/page")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    public BaseResponse<Page<Applicant>> listApplicantByPage(@RequestBody ApplicantQueryRequest postQueryRequest) {
        long current = postQueryRequest.getCurrent();
        long size = postQueryRequest.getPageSize();
        Page<Applicant> postPage = applicantService.page(new Page<>(current, size),
                applicantService.getQueryWrapper(postQueryRequest));
        return ResultUtils.success(postPage);
    }

    /**
     * 分页获取列表（封装类）
     *
     * @param postQueryRequest
     * @return
     */
    @PostMapping("/list/page/vo")
    public BaseResponse<Page<ApplicantVO>> listApplicantVOByPage(@RequestBody ApplicantQueryRequest postQueryRequest) {
        long current = postQueryRequest.getCurrent();
        long size = postQueryRequest.getPageSize();
        // 限制爬虫
        ThrowUtils.throwIf(size > 20, ErrorCode.PARAMS_ERROR);
        Page<Applicant> applicantPage = applicantService.page(new Page<>(current, size),
                applicantService.getQueryWrapper(postQueryRequest));
        return ResultUtils.success(applicantService.getApplicantVOPage(applicantPage));
    }

    /**
     * 完善个人资料
     *
     * @param applicantUpdateMyRequest
     * @param request
     * @return
     */
    @PostMapping("/update/my")
    public BaseResponse<Boolean> updateMyApplicant(@RequestBody ApplicantUpdateMyRequest applicantUpdateMyRequest,
                                              HttpServletRequest request) {
        if (applicantUpdateMyRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User loginUser = userService.getLoginUser(request);

        //获取当前登录人身份的applicant角色信息
        QueryWrapper<Applicant> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Applicant::getUserId, loginUser.getUserAccount());

        Applicant oldApplicant = applicantService.getOne(queryWrapper);

        oldApplicant.setTelNum(applicantUpdateMyRequest.getTelNum());
        oldApplicant.setAge(applicantUpdateMyRequest.getAge());
        oldApplicant.setSex(applicantUpdateMyRequest.getSex());
        oldApplicant.setBg(applicantUpdateMyRequest.getBg());
        oldApplicant.setGen(applicantUpdateMyRequest.getGen());
        oldApplicant.setLocation(applicantUpdateMyRequest.getLocation());
        oldApplicant.setMajor(applicantUpdateMyRequest.getMajor());
        oldApplicant.setDescription(applicantUpdateMyRequest.getDescription());

        List<String> tags = applicantUpdateMyRequest.getTags();
        if (tags != null) {
            oldApplicant.setTags(JSONUtil.toJsonStr(tags));
        }
        boolean result = applicantService.updateById(oldApplicant);

        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(true);
    }

    @GetMapping("/get/my/applicant")
    public BaseResponse<Applicant> getApplicantVOByUserId(@RequestParam String userId) {

        QueryWrapper<Applicant> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(Applicant::getUserId, userId);

        Applicant applicant = applicantService.getOne(queryWrapper);

        return ResultUtils.success(applicant);
    }

    // 更新 Applicant 和 Profile 数据
    @PostMapping("/updateAll")
    public boolean updateUserData(@RequestBody UpdateApplicantAndProfileRequest request) {
        String userId = request.getUserId();

        // 更新 applicant
        applicantService.lambdaUpdate()
                .eq(Applicant::getUserId, userId)
                .set(Applicant::getUserName, request.getApplicant().getUserName())
                .set(Applicant::getTelNum, request.getApplicant().getTelNum())
                .set(Applicant::getAge, request.getApplicant().getAge())
                .set(Applicant::getSex, request.getApplicant().getSex())
                .set(Applicant::getBg, request.getApplicant().getBg())
                .set(Applicant::getGen, request.getApplicant().getGen())
                .set(Applicant::getLocation, request.getApplicant().getLocation())
                .set(Applicant::getMajor, request.getApplicant().getMajor())
                .set(Applicant::getDescription, request.getApplicant().getDescription())
                .set(Applicant::getTags, request.getApplicant().getTags())
                .set(Applicant::getLink, request.getApplicant().getLink())
                .set(Applicant::getDegree, request.getApplicant().getDegree())
                .set(Applicant::getGpa, request.getApplicant().getGpa())
                .set(Applicant::getEmail, request.getApplicant().getEmail())
                .update();

        // 获取 profileId
        String profileId = userProfileService.lambdaQuery()
                .eq(UserProfile::getUserId, userId)
                .oneOpt()
                .map(UserProfile::getProfileId)
                .orElse(null);

        if (profileId != null) {
            // 更新 profile
            profileService.lambdaUpdate()
                    .eq(Profile::getProfileId, profileId)
                    .set(Profile::getUserName, request.getProfile().getUserName())
                    .set(Profile::getCampusExperience, request.getProfile().getCampusExperience())
                    .set(Profile::getWorkExperience, request.getProfile().getWorkExperience())
                    .set(Profile::getProjectExperience, request.getProfile().getProjectExperience())
                    .set(Profile::getPersonSkill, request.getProfile().getPersonSkill())
                    .set(Profile::getPaper, request.getProfile().getPaper())
                    .set(Profile::getJobIntention, request.getProfile().getJobIntention())
                    .set(Profile::getLocation, request.getProfile().getLocation())
                    .set(Profile::getOthers, request.getProfile().getOthers())
                    .set(Profile::getSelfDesc, request.getProfile().getSelfDesc())
                    .update();
        }

        return true;
    }

    // 查询 Applicant 和 Profile 简要信息
    @GetMapping("/applicant/info")
    public BaseResponse<Map<String, Object>>  getUserInfo(@RequestParam String userId) {
        Map<String, Object> result = new HashMap<>();

        Applicant applicant = applicantService.lambdaQuery()
                .eq(Applicant::getUserId, userId)
                .select(
                        Applicant::getId,
                        Applicant::getUserId,
                        Applicant::getUserName,
                        Applicant::getTelNum,
                        Applicant::getAge,
                        Applicant::getSex,
                        Applicant::getBg,
                        Applicant::getGen,
                        Applicant::getLocation,
                        Applicant::getMajor,
                        Applicant::getDescription,
                        Applicant::getTags,
                        Applicant::getLink,
                        Applicant::getDegree,
                        Applicant::getGpa,
                        Applicant::getEmail
                ).one();

        String profileId = userProfileService.lambdaQuery()
                .eq(UserProfile::getUserId, userId)
                .oneOpt()
                .map(UserProfile::getProfileId)
                .orElse(null);

        Profile profile = null;
        if (profileId != null) {
            profile = profileService.lambdaQuery()
                    .eq(Profile::getProfileId, profileId)
                    .select(
                            Profile::getId,
                            Profile::getProfileId,
                            Profile::getPath,
                            Profile::getUserName,
                            Profile::getCampusExperience,
                            Profile::getWorkExperience,
                            Profile::getProjectExperience,
                            Profile::getPersonSkill,
                            Profile::getPaper,
                            Profile::getJobIntention,
                            Profile::getLocation,
                            Profile::getOthers,
                            Profile::getSelfDesc
                    ).one();
        }

        result.put("applicant", applicant);
        result.put("profile", profile);
        return ResultUtils.success(result) ;
    }

}
